package aigle.idm.diagraph.tp3.diagram_default_root.part;

import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.ui.URIEditorInput;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecoretools.diagram.ui.outline.AbstractDiagramsOutlinePage;
import org.eclipse.emf.ecoretools.diagram.ui.outline.AbstractModelNavigator;
import org.eclipse.emf.ecoretools.diagram.ui.outline.IOutlineMenuConstants;
import org.eclipse.emf.ecoretools.diagram.ui.outline.actions.CreateDiagramAction;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gmf.runtime.common.ui.services.marker.MarkerNavigationService;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeNodeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocument;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocument;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocumentProvider;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.parts.DiagramDocumentEditor;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorMatchingStrategy;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.navigator.resources.ProjectExplorer;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

import aigle.idm.diagraph.tp3.Recette;

/**
 * @generated
 */
public class Tp3DiagramEditor extends DiagramDocumentEditor implements
		IGotoMarker {

	/**
	 * @generated
	 */
	public static final String ID = "aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3DiagramEditorID"; //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final String CONTEXT_ID = "aigle.idm.diagraph.tp3.diagram_default_root.ui.diagramContext"; //$NON-NLS-1$

	/**
	 * @generated
	 */
	public Tp3DiagramEditor() {
		super(true);
	}

	/**
	 * @generated
	 */
	protected String getContextID() {
		return CONTEXT_ID;
	}

	/**
	 * @generated
	 */
	protected PaletteRoot createPaletteRoot(PaletteRoot existingPaletteRoot) {
		PaletteRoot root = super.createPaletteRoot(existingPaletteRoot);
		new aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3PaletteFactory()
				.fillPalette(root);
		return root;
	}

	/**
	 * @generated
	 */
	protected PreferencesHint getPreferencesHint() {
		return aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3DiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT;
	}

	/**
	 * @generated
	 */
	public String getContributorId() {
		return aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3DiagramEditorPlugin.ID;
	}

	/**
	 * DIAGRAPH modified 5
	 * @generated
	 */
	class Tp3ModelNavigator extends AbstractModelNavigator {
		public Tp3ModelNavigator(Composite parent,
				IDiagramWorkbenchPart diagEditor, IPageSite pageSite) {
			super(parent, diagEditor, pageSite);
		}

		/**
		 * DIAGRAPH modified 6
		 * @generated
		 */
		@Override
		protected AdapterFactory getAdapterFactory() {
			return aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3DiagramEditorPlugin
					.getInstance().getItemProvidersAdapterFactory();

		}

		/**
		 * DIAGRAPH modified 7
		 * @generated
		 */
		@Override
		protected void createDiagramsMenu(IMenuManager manager,
				EObject selectedObject) {
			super.createDiagramsMenu(manager, selectedObject);
			if (selectedObject instanceof Recette) {
				manager.appendToGroup(
						IOutlineMenuConstants.NEW_GROUP,
						new CreateDiagramAction(
								selectedObject,
								getDiagramResource(),
								Integer.toString(aigle.idm.diagraph.tp3.diagram_default_root.edit.parts.RecetteEditPart.VISUAL_ID),
								Tp3DiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT));
			}
		}
	}

	/**
	 * DIAGRAPH modified 8
	 * @generated
	 */
	class Tp3DiagramOutlinePage extends AbstractDiagramsOutlinePage {
		/**
		 * DIAGRAPH modified 9
		 * @generated
		 */
		public Tp3DiagramOutlinePage(DiagramEditor editor) {
			super(editor);
		}

		/**
		 * DIAGRAPH modified 10
		 * @generated
		 */
		@Override
		public void dispose() {
			super.dispose();
		}

		/**
		 * DIAGRAPH modified 11
		 * @generated
		 */
		@Override
		protected void selectAssociatedPartsInEditor() {
			super.selectAssociatedPartsInEditor();
		}

		/**
		 * DIAGRAPH modified 12
		 * @generated
		 */
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			super.selectionChanged(event);
		}

		/**
		 * DIAGRAPH modified 13
		 * @generated
		 */
		@Override
		protected AbstractModelNavigator createNavigator(Composite parent,
				IPageSite pageSite) {
			return new Tp3ModelNavigator(parent, getEditor(), pageSite);
		}

		/**
		 * DIAGRAPH modified 14
		 * @generated
		 */
		@Override
		protected IPreferenceStore getPreferenceStore() {
			return aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3DiagramEditorPlugin
					.getInstance().getPreferenceStore();

		}

		/**
		 * DIAGRAPH modified 15
		 * @generated
		 */
		@Override
		protected String getEditorID() {
			return aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3DiagramEditor.ID;
		}

		/**
		 * DIAGRAPH modified 16
		 * @generated
		 */
		private void log(List shapes) {
			for (Object shape : shapes) {
				if (shape instanceof ShapeNodeEditPart) {
					this.getEditor().getDiagramGraphicalViewer()
							.setSelection(new StructuredSelection(shape));
					System.out.println(((ShapeNodeEditPart) shape).getModel()
							.toString());
					ShapeNodeEditPart shapeNodeEditPart = (ShapeNodeEditPart) shape;
					log(shapeNodeEditPart.getChildren());
				}
			}
		}

		/**
		 * Open the new diagram in the same editor
		 */
		/**
		 * DIAGRAPH modified 17
		 * @generated
		 */
		@Override
		protected void handleDoubleClickEvent() {
			IStructuredSelection selection = (IStructuredSelection) getSelection();
			Object selectedObject = selection.getFirstElement();
			if (selectedObject != null && selectedObject instanceof Diagram) {
				Diagram d = (Diagram) selectedObject;
				EList ch = d.getPersistedChildren();
				for (Object object : ch) {
					System.out.println(object.getClass().getName());
				}
			}
			DiagramEditor diag = this.getEditor();
			EList ch = diag.getDiagram().getPersistedChildren();
			for (Object object : ch) {
				System.out.println(object.getClass().getName());
				if (object instanceof Node) {
					Node nod = (Node) object;
					try {
						this.getEditor()
								.getDiagramGraphicalViewer()
								.setSelection(
										new StructuredSelection(diag
												.getDiagramEditPart()
												.getChildren().get(0)));
					} catch (Exception e) {
						// TODO: handle exception
					}
					EditPartViewer edpv = diag.getDiagramEditPart().getViewer();
				}
			}

			if (selectedObject != null
					&& selectedObject instanceof Diagram
					&& getEditor().getDiagram() != selectedObject
					&& getEditor().getDiagram().eResource()
							.equals(((Diagram) selectedObject).eResource())) {
				((aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3DiagramEditor) getEditor())
						.setDiagram((Diagram) selectedObject);
			}
		}
	}

	/**
	 * DIAGRAPH modified 1b
	 * @generated
	 */
	private void hideEditor() {
		IWorkbenchPage page = PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow().getActivePage();
		for (IEditorReference iEditorReference : page.getEditorReferences()) {
			System.out.println("@@@ " + iEditorReference.getName());
			if (iEditorReference.getName().contains("root_diagram#")) //FP121109
				;//page.hideEditor(iEditorReference);	
		}
	}

	/**
	 * DIAGRAPH modified 1
	 * @generated
	 */
	public Object getAdapter(Class type) {
		// todo - see:
		// http://www.eclipse.org/articles/Article-Tabbed-Properties/tabbed_properties_view.html
		// http://www.eclipse.org/webtools/wst/components/sse/designs/EditorSelection.html
		// http://www.ibm.com/developerworks/opensource/library/os-ecllink/

		if (type == IShowInTargetList.class) {
			return new IShowInTargetList() {
				public String[] getShowInTargetIds() {
					return new String[] { ProjectExplorer.VIEW_ID };
				}
			};
		}
		if (type == IContentOutlinePage.class) {
			IContentOutlinePage contentOutlinePage = createContentOutlinePage();
			if (contentOutlinePage == null)
				contentOutlinePage = (IContentOutlinePage) super
						.getAdapter(type);
			hideEditor(); //hack 
			return contentOutlinePage;
		}
		return super.getAdapter(type);
	}

	/**
	 * DIAGRAPH modified 2
	 * @generated
	 */
	protected IContentOutlinePage createContentOutlinePage() {
		/* In case of extension-point mechanism
		return DiagramOutlineProvider
				.getOutlineFactory("org.isoe.eval.Tp3.outline",
						"foobarimpl").create(this);*/

		IContentOutlinePage result = new Tp3DiagramOutlinePage(this);
		System.out.println(result.getClass().getName());
		System.out.println("Persisted Children:");
		for (Object object : this.getDiagram().getPersistedChildren()) {
			System.out.println("changed" + object.toString());
		}
		result.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				System.out.println("changed");
			}
		});
		return result;
	}

	/**
	 * @generated
	 */
	protected IDocumentProvider getDocumentProvider(IEditorInput input) {
		if (input instanceof IFileEditorInput
				|| input instanceof URIEditorInput) {
			return aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3DiagramEditorPlugin
					.getInstance().getDocumentProvider();
		}
		return super.getDocumentProvider(input);
	}

	/**
	 * @generated
	 */
	public TransactionalEditingDomain getEditingDomain() {
		IDocument document = getEditorInput() != null ? getDocumentProvider()
				.getDocument(getEditorInput()) : null;
		if (document instanceof IDiagramDocument) {
			return ((IDiagramDocument) document).getEditingDomain();
		}
		return super.getEditingDomain();
	}

	/**
	 * @generated
	 */
	protected void setDocumentProvider(IEditorInput input) {
		if (input instanceof IFileEditorInput
				|| input instanceof URIEditorInput) {
			setDocumentProvider(aigle.idm.diagraph.tp3.diagram_default_root.part.Tp3DiagramEditorPlugin
					.getInstance().getDocumentProvider());
		} else {
			super.setDocumentProvider(input);
		}
	}

	/**
	 * @generated
	 */
	public void gotoMarker(IMarker marker) {
		MarkerNavigationService.getInstance().gotoMarker(this, marker);
	}

	/**
	 * @generated
	 */
	public boolean isSaveAsAllowed() {
		return true;
	}

	/**
	 * @generated
	 */
	public void doSaveAs() {
		performSaveAs(new NullProgressMonitor());
	}

	/**
	 * @generated
	 */
	protected void performSaveAs(IProgressMonitor progressMonitor) {
		Shell shell = getSite().getShell();
		IEditorInput input = getEditorInput();
		SaveAsDialog dialog = new SaveAsDialog(shell);
		IFile original = input instanceof IFileEditorInput ? ((IFileEditorInput) input)
				.getFile() : null;
		if (original != null) {
			dialog.setOriginalFile(original);
		}
		dialog.create();
		IDocumentProvider provider = getDocumentProvider();
		if (provider == null) {
			// editor has been programmatically closed while the dialog was open
			return;
		}
		if (provider.isDeleted(input) && original != null) {
			String message = NLS
					.bind(aigle.idm.diagraph.tp3.diagram_default_root.part.Messages.Tp3DiagramEditor_SavingDeletedFile,
							original.getName());
			dialog.setErrorMessage(null);
			dialog.setMessage(message, IMessageProvider.WARNING);
		}
		if (dialog.open() == Window.CANCEL) {
			if (progressMonitor != null) {
				progressMonitor.setCanceled(true);
			}
			return;
		}
		IPath filePath = dialog.getResult();
		if (filePath == null) {
			if (progressMonitor != null) {
				progressMonitor.setCanceled(true);
			}
			return;
		}
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		IFile file = workspaceRoot.getFile(filePath);
		final IEditorInput newInput = new FileEditorInput(file);
		// Check if the editor is already open
		IEditorMatchingStrategy matchingStrategy = getEditorDescriptor()
				.getEditorMatchingStrategy();
		IEditorReference[] editorRefs = PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow().getActivePage()
				.getEditorReferences();
		for (int i = 0; i < editorRefs.length; i++) {
			if (matchingStrategy.matches(editorRefs[i], newInput)) {
				MessageDialog
						.openWarning(
								shell,
								aigle.idm.diagraph.tp3.diagram_default_root.part.Messages.Tp3DiagramEditor_SaveAsErrorTitle,
								aigle.idm.diagraph.tp3.diagram_default_root.part.Messages.Tp3DiagramEditor_SaveAsErrorMessage);
				return;
			}
		}
		boolean success = false;
		try {
			provider.aboutToChange(newInput);
			getDocumentProvider(newInput).saveDocument(progressMonitor,
					newInput,
					getDocumentProvider().getDocument(getEditorInput()), true);
			success = true;
		} catch (CoreException x) {
			IStatus status = x.getStatus();
			if (status == null || status.getSeverity() != IStatus.CANCEL) {
				ErrorDialog
						.openError(
								shell,
								aigle.idm.diagraph.tp3.diagram_default_root.part.Messages.Tp3DiagramEditor_SaveErrorTitle,
								aigle.idm.diagraph.tp3.diagram_default_root.part.Messages.Tp3DiagramEditor_SaveErrorMessage,
								x.getStatus());
			}
		} finally {
			provider.changed(newInput);
			if (success) {
				setInput(newInput);
			}
		}
		if (progressMonitor != null) {
			progressMonitor.setCanceled(!success);
		}
	}

	/**
	 * @generated
	 */
	public ShowInContext getShowInContext() {
		return new ShowInContext(getEditorInput(), getNavigatorSelection());
	}

	/**
	 * @generated
	 */
	private ISelection getNavigatorSelection() {
		IDiagramDocument document = getDiagramDocument();
		if (document == null) {
			return StructuredSelection.EMPTY;
		}
		Diagram diagram = document.getDiagram();
		if (diagram == null || diagram.eResource() == null) {
			return StructuredSelection.EMPTY;
		}
		IFile file = WorkspaceSynchronizer.getFile(diagram.eResource());
		if (file != null) {
			aigle.idm.diagraph.tp3.diagram_default_root.navigator.Tp3NavigatorItem item = new aigle.idm.diagraph.tp3.diagram_default_root.navigator.Tp3NavigatorItem(
					diagram, file, false);
			return new StructuredSelection(item);
		}
		return StructuredSelection.EMPTY;
	}

	/**
	 * DIAGRAPH modified 3
	 * @generated
	 */
	protected void configureGraphicalViewer() {
		super.configureGraphicalViewer();
		aigle.idm.diagraph.tp3.diagram_default_root.part.DiagramEditorContextMenuProvider provider = new aigle.idm.diagraph.tp3.diagram_default_root.part.DiagramEditorContextMenuProvider(
				this, getDiagramGraphicalViewer());
		getDiagramGraphicalViewer().setContextMenu(provider);
		getSite().registerContextMenu(ActionIds.DIAGRAM_EDITOR_CONTEXT_MENU,
				provider, getDiagramGraphicalViewer());
	}

	/**
	 * DIAGRAPH modified 4
	 * @generated
	 */
	public void setDiagram(final Diagram diagram) { //FP 
		if (Display.getCurrent() != Display.getDefault()) {
			Display.getDefault().asyncExec(new Runnable() {
				public void run() {
					// navigation_added.set(diagram);
				}
			});
		} else {
			// navigation_added.set(diagram);
		}
	}

}
